package com.panfeng.xcloud.boss.provider.assets.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.panfeng.xcloud.boss.provider.assets.dao.mapper.*;
import com.panfeng.xcloud.boss.provider.assets.dto.request.*;
import com.panfeng.xcloud.boss.provider.assets.dto.response.*;
import com.panfeng.xcloud.boss.provider.assets.service.IExecuteOrderService;
import com.panfeng.xcloud.boss.provider.assets.service.IUserQuantOperateService;
import com.panfeng.xcloud.boss.provider.assets.service.exchange.IExchangeOperateService;
import com.panfeng.xcloud.boss.provider.assets.utils.OrderNoGenerate;
import com.panfeng.xcloud.boss.provider.assets.web.vo.response.OpenQuantBotRespVO;
import com.panfeng.xcloud.boss.provider.assets.web.vo.response.UserQuantBotRespVO;
import com.panfeng.xcloud.boss.provider.dto.request.*;
import com.panfeng.xcloud.boss.provider.rpc.member.UserInfoFeignApi;
import com.panfeng.xcloud.common.core.configuration.DataDictionaryConfig;
import com.panfeng.xcloud.common.core.constants.RedisConstants;
import com.panfeng.xcloud.common.core.enums.*;
import com.panfeng.xcloud.common.core.exceptions.BaseBizException;
import com.panfeng.xcloud.common.core.utils.*;
import com.panfeng.xcloud.common.core.web.vo.OrderDetailResponseVO;
import com.panfeng.xcloud.common.core.web.vo.TradeResponseVO;
import com.panfeng.xcloud.dao.assets.entity.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserQuantOperateServiceImpl implements IUserQuantOperateService {

    @Autowired
    private UserExchangePwdMapperExt userExchangePwdMapperExt;

    @Autowired
    private UserWalletInfoMapperExt userWalletInfoMapperExt;

    @Value("${xdcloud.des3.secret-key}")
    private String secrectKey;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CoinExchangeSetMapperExt coinExchangeSetMapperExt;

    @Autowired
    private DataDictionaryConfig dataDictionaryConfig;

    @Autowired
    private CoinListMapperExt coinListMapperExt;

    @Autowired
    private UserBotMapperExt userBotMapperExt;

    @Autowired
    private ProfitAndFeeDetailMapperExt profitAndFeeDetailMapperExt;

    @Autowired
    private IExecuteOrderService executeOrderServiceImpl;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserInfoFeignApi userInfoFeignApi;

    @Autowired
    private IExchangeOperateService iExchangeOperateService;

    /**
     * 操作--开仓,清仓,锁仓,解锁,停止机器人
     *
     * @param operateBotReqDTO
     */
    @Override
    public OperateBotRespDTO operateBot(OperateBotReqDTO operateBotReqDTO) {
        //判断用户操作提交频率，避免重复提交
        checkOperateSubmitFrequency(RedisConstants.QUANT_OPERATE_FREQUENCY_CACHE + operateBotReqDTO.getUserId());

        //获取配置杠杆倍数
        CoinExchangeSet usingCoinExchangeSet = getUsingCoinExchangeSet(operateBotReqDTO.getUserId(), operateBotReqDTO.getExchangeType(), operateBotReqDTO.getDestinationCoin(), operateBotReqDTO.getSourceCoin(), operateBotReqDTO.getDirection());
        operateBotReqDTO.setLeverRate(usingCoinExchangeSet.getLeverRate());

        //获取机器人key
        String userBotKey = KeyContactUtil.getUserBotKey(operateBotReqDTO.getExchangeType(), operateBotReqDTO.getDirection(), operateBotReqDTO.getLeverRate(),
                operateBotReqDTO.getDestinationCoin(), operateBotReqDTO.getSourceCoin(), operateBotReqDTO.getUserId());

        //获取机器人对象
        QuantBotDetailDTO quantBotDetailDTO = JSONObject.parseObject(stringRedisTemplate.opsForValue().get(userBotKey), QuantBotDetailDTO.class);

        //执行具体操作
        OperateBotRespDTO operateBotRespDTO = toExecuteOperate(operateBotReqDTO, quantBotDetailDTO, userBotKey);

        return operateBotRespDTO;
    }

    /**
     * 批量操作--开仓,清仓,锁仓,解锁,停止机器人
     *
     * @param batchOperateBotReqDTO
     */
    @Override
    //@Async("asyncExecutor")
    public BatchOperateBotRespDTO batchOperateBot(BatchOperateBotReqDTO batchOperateBotReqDTO) {
        //判断用户交易提交频率，避免重复提交
        checkOperateSubmitFrequency(RedisConstants.QUANT_OPERATE_FREQUENCY_CACHE + batchOperateBotReqDTO.getUserId());

        UserWalletInfo userWalletInfo = new UserWalletInfo();
        userWalletInfo.setUserId(batchOperateBotReqDTO.getUserId());
        userWalletInfo.setChainName(ChainTypeEnum.TRON.getCode());
        userWalletInfo.setCoinName(CoinTypeEnum.USDT.getCode());
        UserWalletInfo walletInfo = userWalletInfoMapperExt.selectOne(userWalletInfo);
        BigDecimal pointMin = new BigDecimal(dataDictionaryConfig.getCodeToNameMap().get(
                DataDictionaryTypeEnum.start_robot_point_balance_min.getCode()));

        //判断点卡余额是否足够
        if (walletInfo.getPointBalance().compareTo(pointMin) < 0) {
            throw new BaseBizException(ResponseStatusEnum.WALLET_BALANCE_NOT_ENOUGH);
        }

        List<BatchCoinListItemReqVO> batchCoinList = batchOperateBotReqDTO.getBatchCoinList();

        for (BatchCoinListItemReqVO batchItem : batchCoinList) {
            try {
                CoinExchangeSet usingCoinExchangeSet = getUsingCoinExchangeSet(batchOperateBotReqDTO.getUserId(), batchItem.getExchangeType(),
                        batchItem.getDestinationCoin(), batchItem.getSourceCoin(), batchItem.getDirection());

                OperateBotReqDTO operateBotReqDTO = new OperateBotReqDTO();
                operateBotReqDTO.setUserId(batchOperateBotReqDTO.getUserId());
                operateBotReqDTO.setOperateType(batchOperateBotReqDTO.getOperateType());
                operateBotReqDTO.setDestinationCoin(batchItem.getDestinationCoin());
                operateBotReqDTO.setSourceCoin(batchItem.getSourceCoin());
                operateBotReqDTO.setDirection(batchItem.getDirection());
                operateBotReqDTO.setLeverRate(batchItem.getLeverRate());
                operateBotReqDTO.setExchangeType(batchItem.getExchangeType());
                operateBotReqDTO.setAmount(usingCoinExchangeSet.getInitOrderPosition());

                String userBotKey = KeyContactUtil.getUserBotKey(batchItem.getExchangeType(), batchItem.getDirection(),
                        operateBotReqDTO.getLeverRate(), batchItem.getDestinationCoin(), batchItem.getSourceCoin(), batchOperateBotReqDTO.getUserId());

                QuantBotDetailDTO quantBotDetailDTO = JSONObject.parseObject(stringRedisTemplate.opsForValue().get(userBotKey), QuantBotDetailDTO.class);

                //执行具体操作
                toExecuteOperate(operateBotReqDTO, quantBotDetailDTO, userBotKey);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                userInfoFeignApi.sendEmail(
                        new SendEmailReqDTO("UserId:" + batchOperateBotReqDTO.getUserId()
                                + "  交易对:" + batchItem.getDestinationCoin().concat(batchItem.getSourceCoin())
                                + "  方向:" + batchItem.getDirection()
                                + "  批量交易操作异常:" + StringUtils.printStackTraceToString(e)));
            }
        }

        return null;
    }

    /**
     * 更新币种交易设置
     *
     * @param updateStrategyReqDTO
     * @return
     */
    @Override
    public UpdateStrategyRespDTO updateStrategy(UpdateStrategyReqDTO updateStrategyReqDTO) {
        BigDecimal div = new BigDecimal("100");
        updateStrategyReqDTO.setStopProfitRatio(updateStrategyReqDTO.getStopProfitRatio().divide(div));
        updateStrategyReqDTO.setStopProfitBackRatio(updateStrategyReqDTO.getStopProfitBackRatio().divide(div));
        updateStrategyReqDTO.setAddPosition1(updateStrategyReqDTO.getAddPosition1().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition2(updateStrategyReqDTO.getAddPosition2().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition3(updateStrategyReqDTO.getAddPosition3().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition4(updateStrategyReqDTO.getAddPosition4().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition5(updateStrategyReqDTO.getAddPosition5().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition6(updateStrategyReqDTO.getAddPosition6().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition7(updateStrategyReqDTO.getAddPosition7().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition8(updateStrategyReqDTO.getAddPosition8().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition9(updateStrategyReqDTO.getAddPosition9().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition10(updateStrategyReqDTO.getAddPosition10().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition11(updateStrategyReqDTO.getAddPosition11().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition12(updateStrategyReqDTO.getAddPosition12().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition13(updateStrategyReqDTO.getAddPosition13().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition14(updateStrategyReqDTO.getAddPosition14().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition15(updateStrategyReqDTO.getAddPosition15().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition16(updateStrategyReqDTO.getAddPosition16().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition17(updateStrategyReqDTO.getAddPosition17().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition18(updateStrategyReqDTO.getAddPosition18().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition19(updateStrategyReqDTO.getAddPosition19().divide(div).abs().negate());
        updateStrategyReqDTO.setAddPosition20(updateStrategyReqDTO.getAddPosition20().divide(div).abs().negate());
        updateStrategyReqDTO.setStopLossesRatio(updateStrategyReqDTO.getStopLossesRatio().divide(div));
        updateStrategyReqDTO.setAddPositionBackRatio(updateStrategyReqDTO.getAddPositionBackRatio().divide(div));
        updateStrategyReqDTO.setBuyStopRate(updateStrategyReqDTO.getBuyStopRate().divide(div));
        updateStrategyReqDTO.setSellStopRate(updateStrategyReqDTO.getSellStopRate().divide(div));
        updateStrategyReqDTO.setStopLossProfit(updateStrategyReqDTO.getStopLossProfit().divide(div));
        updateStrategyReqDTO.setAntiStopProfitRatio(updateStrategyReqDTO.getAntiStopProfitRatio().divide(div));
        updateStrategyReqDTO.setAntiAddPosition1(updateStrategyReqDTO.getAntiAddPosition1().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition2(updateStrategyReqDTO.getAntiAddPosition2().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition3(updateStrategyReqDTO.getAntiAddPosition3().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition4(updateStrategyReqDTO.getAntiAddPosition4().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition5(updateStrategyReqDTO.getAntiAddPosition5().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition6(updateStrategyReqDTO.getAntiAddPosition6().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition7(updateStrategyReqDTO.getAntiAddPosition7().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition8(updateStrategyReqDTO.getAntiAddPosition8().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition9(updateStrategyReqDTO.getAntiAddPosition9().divide(div).abs());
        updateStrategyReqDTO.setAntiAddPosition10(updateStrategyReqDTO.getAntiAddPosition10().divide(div).abs());

        //校验杠杆倍数是否可用
        boolean leverRateCanUse = iExchangeOperateService.leverRateCanUse(updateStrategyReqDTO.getExchangeType(), updateStrategyReqDTO.getUserId(),
                updateStrategyReqDTO.getDestinationCoin(), updateStrategyReqDTO.getSourceCoin(), updateStrategyReqDTO.getLeverRate());
        if (!leverRateCanUse) {
            throw new BaseBizException(ResponseStatusEnum.ERROR_LEVERRATE);
        }

        //调用交易所接口调整杠杆倍数(有些需要,有些不需要,这里做统一处理)
        boolean changeLeverResult = iExchangeOperateService.changeLeverRate(updateStrategyReqDTO.getExchangeType(), updateStrategyReqDTO.getUserId(),
                updateStrategyReqDTO.getDestinationCoin(), updateStrategyReqDTO.getSourceCoin(), updateStrategyReqDTO.getLeverRate());
        if (!changeLeverResult) {
            throw new BaseBizException(ResponseStatusEnum.CHANGE_LEVERRATE_ERROR);
        }

        UpdateStrategyRespDTO respDTO = toExecuteUpdateStrategy(updateStrategyReqDTO);

        return respDTO;
    }

    /**
     * 批量更新交易设置
     *
     * @param batchUpdateStrategyReqDTO
     * @return
     */
    @Override
    //@Async("asyncExecutor")
    public BatchUpdateStrategyRespDTO batchUpdateStrategy(BatchUpdateStrategyReqDTO batchUpdateStrategyReqDTO) {
        UpdateStrategyReqDTO dto = ConvertUtils.convert(batchUpdateStrategyReqDTO, UpdateStrategyReqDTO.class);

        BigDecimal div = new BigDecimal("100");
        dto.setStopProfitRatio(dto.getStopProfitRatio().divide(div));
        dto.setStopProfitBackRatio(dto.getStopProfitBackRatio().divide(div));
        dto.setAddPosition1(dto.getAddPosition1().divide(div).abs().negate());
        dto.setAddPosition2(dto.getAddPosition2().divide(div).abs().negate());
        dto.setAddPosition3(dto.getAddPosition3().divide(div).abs().negate());
        dto.setAddPosition4(dto.getAddPosition4().divide(div).abs().negate());
        dto.setAddPosition5(dto.getAddPosition5().divide(div).abs().negate());
        dto.setAddPosition6(dto.getAddPosition6().divide(div).abs().negate());
        dto.setAddPosition7(dto.getAddPosition7().divide(div).abs().negate());
        dto.setAddPosition8(dto.getAddPosition8().divide(div).abs().negate());
        dto.setAddPosition9(dto.getAddPosition9().divide(div).abs().negate());
        dto.setAddPosition10(dto.getAddPosition10().divide(div).abs().negate());
        dto.setAddPosition11(dto.getAddPosition11().divide(div).abs().negate());
        dto.setAddPosition12(dto.getAddPosition12().divide(div).abs().negate());
        dto.setAddPosition13(dto.getAddPosition13().divide(div).abs().negate());
        dto.setAddPosition14(dto.getAddPosition14().divide(div).abs().negate());
        dto.setAddPosition15(dto.getAddPosition15().divide(div).abs().negate());
        dto.setAddPosition16(dto.getAddPosition16().divide(div).abs().negate());
        dto.setAddPosition17(dto.getAddPosition17().divide(div).abs().negate());
        dto.setAddPosition18(dto.getAddPosition18().divide(div).abs().negate());
        dto.setAddPosition19(dto.getAddPosition19().divide(div).abs().negate());
        dto.setAddPosition20(dto.getAddPosition20().divide(div).abs().negate());
        dto.setStopLossesRatio(dto.getStopLossesRatio().divide(div));
        dto.setAddPositionBackRatio(dto.getAddPositionBackRatio().divide(div));
        dto.setBuyStopRate(dto.getBuyStopRate().divide(div));
        dto.setSellStopRate(dto.getSellStopRate().divide(div));
        dto.setStopLossProfit(dto.getStopLossProfit().divide(div));
        dto.setAntiStopProfitRatio(dto.getAntiStopProfitRatio().divide(div));
        dto.setAntiAddPosition1(dto.getAntiAddPosition1().divide(div).abs());
        dto.setAntiAddPosition2(dto.getAntiAddPosition2().divide(div).abs());
        dto.setAntiAddPosition3(dto.getAntiAddPosition3().divide(div).abs());
        dto.setAntiAddPosition4(dto.getAntiAddPosition4().divide(div).abs());
        dto.setAntiAddPosition5(dto.getAntiAddPosition5().divide(div).abs());
        dto.setAntiAddPosition6(dto.getAntiAddPosition6().divide(div).abs());
        dto.setAntiAddPosition7(dto.getAntiAddPosition7().divide(div).abs());
        dto.setAntiAddPosition8(dto.getAntiAddPosition8().divide(div).abs());
        dto.setAntiAddPosition9(dto.getAntiAddPosition9().divide(div).abs());
        dto.setAntiAddPosition10(dto.getAntiAddPosition10().divide(div).abs());

        List<BatchCoinListItemReqVO> batchCoinList = batchUpdateStrategyReqDTO.getBatchCoinList();
        for (BatchCoinListItemReqVO batchItem : batchCoinList) {
            try {
                dto.setDestinationCoin(batchItem.getDestinationCoin());
                dto.setSourceCoin(batchItem.getSourceCoin());
                dto.setExchangeType(batchItem.getExchangeType());
                dto.setDirection(batchItem.getDirection());

                //校验杠杆倍数是否可用
                boolean leverRateCanUse = iExchangeOperateService.leverRateCanUse(dto.getExchangeType(), dto.getUserId(),
                        dto.getDestinationCoin(), dto.getSourceCoin(), dto.getLeverRate());
                if (!leverRateCanUse) {
                    throw new BaseBizException(ResponseStatusEnum.ERROR_LEVERRATE);
                }

                //调用交易所接口调整杠杆倍数(有些需要,有些不需要,这里做统一处理)
                boolean changeLeverResult = iExchangeOperateService.changeLeverRate(dto.getExchangeType(), dto.getUserId(),
                        dto.getDestinationCoin(), dto.getSourceCoin(), dto.getLeverRate());
                if (!changeLeverResult) {
                    throw new BaseBizException(ResponseStatusEnum.CHANGE_LEVERRATE_ERROR);
                }
                toExecuteUpdateStrategy(dto);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                userInfoFeignApi.sendEmail(
                        new SendEmailReqDTO("UserId:" + batchUpdateStrategyReqDTO.getUserId()
                                + "  交易对:" + batchItem.getDestinationCoin().concat(batchItem.getSourceCoin())
                                + "  方向:" + batchItem.getDirection()
                                + "  批量更新交易设置操作异常:" + StringUtils.printStackTraceToString(e)));
            }
        }

        return null;
    }

    /**
     * 查询币种交易设置
     *
     * @param queryStrategyReqDTO
     * @return
     */
    @Override
    public QueryStrategyRespDTO queryStrategy(QueryStrategyReqDTO queryStrategyReqDTO) {
        CoinExchangeSet usingCoinExchangeSet = getUsingCoinExchangeSet(queryStrategyReqDTO.getUserId(),
                queryStrategyReqDTO.getExchangeType(), queryStrategyReqDTO.getDestinationCoin(), queryStrategyReqDTO.getSourceCoin(), queryStrategyReqDTO.getDirection());

        QueryStrategyRespDTO respDTO = ConvertUtils.convert(usingCoinExchangeSet, QueryStrategyRespDTO.class);

        BigDecimal mul = new BigDecimal("100");
        respDTO.setStopProfitRatio(respDTO.getStopProfitRatio().multiply(mul));
        respDTO.setStopProfitBackRatio(respDTO.getStopProfitBackRatio().multiply(mul));
        respDTO.setAddPosition1(respDTO.getAddPosition1().multiply(mul).abs());
        respDTO.setAddPosition2(respDTO.getAddPosition2().multiply(mul).abs());
        respDTO.setAddPosition3(respDTO.getAddPosition3().multiply(mul).abs());
        respDTO.setAddPosition4(respDTO.getAddPosition4().multiply(mul).abs());
        respDTO.setAddPosition5(respDTO.getAddPosition5().multiply(mul).abs());
        respDTO.setAddPosition6(respDTO.getAddPosition6().multiply(mul).abs());
        respDTO.setAddPosition7(respDTO.getAddPosition7().multiply(mul).abs());
        respDTO.setAddPosition8(respDTO.getAddPosition8().multiply(mul).abs());
        respDTO.setAddPosition9(respDTO.getAddPosition9().multiply(mul).abs());
        respDTO.setAddPosition10(respDTO.getAddPosition10().multiply(mul).abs());
        respDTO.setAddPosition11(respDTO.getAddPosition11().multiply(mul).abs());
        respDTO.setAddPosition12(respDTO.getAddPosition12().multiply(mul).abs());
        respDTO.setAddPosition13(respDTO.getAddPosition13().multiply(mul).abs());
        respDTO.setAddPosition14(respDTO.getAddPosition14().multiply(mul).abs());
        respDTO.setAddPosition15(respDTO.getAddPosition15().multiply(mul).abs());
        respDTO.setAddPosition16(respDTO.getAddPosition16().multiply(mul).abs());
        respDTO.setAddPosition17(respDTO.getAddPosition17().multiply(mul).abs());
        respDTO.setAddPosition18(respDTO.getAddPosition18().multiply(mul).abs());
        respDTO.setAddPosition19(respDTO.getAddPosition19().multiply(mul).abs());
        respDTO.setAddPosition20(respDTO.getAddPosition20().multiply(mul).abs());
        respDTO.setStopLossesRatio(respDTO.getStopLossesRatio().multiply(mul));
        respDTO.setStopLossProfit(respDTO.getStopLossProfit().multiply(mul));
        respDTO.setAddPositionBackRatio(respDTO.getAddPositionBackRatio().multiply(mul));
        respDTO.setAddPositionTimesModelSwitch(respDTO.getAddPositionTimesModelSwitch());
        respDTO.setAddPositionDynamicTimes(respDTO.getAddPositionDynamicTimes());
        respDTO.setAddPositionFixTimes(respDTO.getAddPositionFixTimes());
        respDTO.setAntiAddPositionTimesModelSwitch(respDTO.getAntiAddPositionTimesModelSwitch());
        respDTO.setAntiAddPositionDynamicTimes(respDTO.getAntiAddPositionDynamicTimes());
        respDTO.setAntiAddPositionFixTimes(respDTO.getAntiAddPositionFixTimes());
        respDTO.setBuyStopRate(respDTO.getBuyStopRate().multiply(mul));
        respDTO.setSellStopRate(respDTO.getSellStopRate().multiply(mul));
        respDTO.setAntiStopProfitRatio(respDTO.getAntiStopProfitRatio().multiply(mul));
        respDTO.setAntiAddPosition1(respDTO.getAntiAddPosition1().multiply(mul).abs());
        respDTO.setAntiAddPosition2(respDTO.getAntiAddPosition2().multiply(mul).abs());
        respDTO.setAntiAddPosition3(respDTO.getAntiAddPosition3().multiply(mul).abs());
        respDTO.setAntiAddPosition4(respDTO.getAntiAddPosition4().multiply(mul).abs());
        respDTO.setAntiAddPosition5(respDTO.getAntiAddPosition5().multiply(mul).abs());
        respDTO.setAntiAddPosition6(respDTO.getAntiAddPosition6().multiply(mul).abs());
        respDTO.setAntiAddPosition7(respDTO.getAntiAddPosition7().multiply(mul).abs());
        respDTO.setAntiAddPosition8(respDTO.getAntiAddPosition8().multiply(mul).abs());
        respDTO.setAntiAddPosition9(respDTO.getAntiAddPosition9().multiply(mul).abs());
        respDTO.setAntiAddPosition10(respDTO.getAntiAddPosition10().multiply(mul).abs());

        respDTO.setExchangeType(queryStrategyReqDTO.getExchangeType());
        respDTO.setSourceCoin(queryStrategyReqDTO.getSourceCoin());
        respDTO.setDestinationCoin(queryStrategyReqDTO.getDestinationCoin());
        respDTO.setUserId(queryStrategyReqDTO.getUserId());
        respDTO.setDirection(queryStrategyReqDTO.getDirection());

        return respDTO;
    }

    /**
     * 获取已开启量化的交易对列表
     *
     * @param openQuantBotReqDTO
     * @return
     */
    @Override
    public UserQuantBotRespVO getOpeningQuantBotList(OpenQuantBotReqDTO openQuantBotReqDTO) {
        UserQuantBotRespVO userQuantBotRespVO = new UserQuantBotRespVO();

        BigDecimal mul = new BigDecimal("100");
        List<UserBot> userBots = new ArrayList<>();

        //查找该用户盈利手续费详情表
        BigDecimal todayFloatProfit = BigDecimal.ZERO;
        BigDecimal totalFloatProfit = BigDecimal.ZERO;
        BigDecimal todayFee = BigDecimal.ZERO;
        BigDecimal totalFee = BigDecimal.ZERO;

        ProfitAndFeeDetail reqDTO = new ProfitAndFeeDetail();
        reqDTO.setUserId(openQuantBotReqDTO.getUserId());
        reqDTO.setExchangeType(openQuantBotReqDTO.getExchangeType());
        List<ProfitAndFeeDetail> profitAndFeeDetails = profitAndFeeDetailMapperExt.selectByProfitAndFeeDetail(reqDTO);
        for (ProfitAndFeeDetail profitAndFeeDetail : profitAndFeeDetails) {
            todayFloatProfit = todayFloatProfit.add(profitAndFeeDetail.getTodayRealizedAmount());
            totalFloatProfit = totalFloatProfit.add(profitAndFeeDetail.getTotalRealizedAmount());
            todayFee = todayFee.add(profitAndFeeDetail.getTodayRealizedFee());
            totalFee = totalFee.add(profitAndFeeDetail.getTotalRealizedFee());
        }

        //找到该用户正在运行中的机器人
        if (StringUtils.isEmpty(openQuantBotReqDTO.getCoin())) {
            userBots = userBotMapperExt.selectBotsByUserId(Integer.valueOf(UserBotStatusTypeEnum.ACTIVE.getCode()), openQuantBotReqDTO.getUserId(), openQuantBotReqDTO.getExchangeType());
        } else {
            List<UserBot> userBotConditions = userBotMapperExt.selectLikeCoin(openQuantBotReqDTO.getUserId(), openQuantBotReqDTO.getCoin(),
                    CoinTypeEnum.USDT.getCode(), openQuantBotReqDTO.getExchangeType(), Integer.valueOf(UserBotStatusTypeEnum.ACTIVE.getCode()));
            userBots.addAll(userBotConditions);
        }

        List<OpenQuantBotRespDTO> dtos = new ArrayList<>();
        List<CoinList> coinList = coinListMapperExt.queryCoinListByExchangeType(openQuantBotReqDTO.getExchangeType(), CoinListStatusTypeEnum.OPEN.code);
        Map<String, String> collectUrlMap = coinList.stream().collect(Collectors.toMap(CoinList::getCollectUrlMapKey, CoinList::getUrl));

        for (int i = 0; i < userBots.size(); i++) {
            UserBot value = userBots.get(i);
            OpenQuantBotRespDTO dto = new OpenQuantBotRespDTO();

            String userBotKey = KeyContactUtil.getUserBotKey(value.getExchangeType(), value.getDirection(), value.getLeverRate(), value.getDestinationCoin(),
                    value.getSourceCoin(), value.getUserId());

            QuantBotDetailDTO quantBotDetailDTO = JSONObject.parseObject(stringRedisTemplate.opsForValue().get(userBotKey), QuantBotDetailDTO.class);

            //用机器人中的卖盘涨幅作为涨幅
            BigDecimal currentRate = new BigDecimal(quantBotDetailDTO.getAskRise());

            //已开启
            if (quantBotDetailDTO.getStatus().equals(UserBotStatusTypeEnum.ACTIVE.getCode())) {
                dto.setContractCode(quantBotDetailDTO.getContractCode());
                //获取对应URL
                dto.setUrl(collectUrlMap.get(KeyContactUtil.getCollectUrlMapKey(value.getDestinationCoin(), value.getDirection())));
                dto.setSourceCoin(value.getSourceCoin());
                dto.setDestinationCoin(value.getDestinationCoin());
                dto.setAmount(new BigDecimal(quantBotDetailDTO.getPositionNum()).setScale(8, BigDecimal.ROUND_DOWN));
                dto.setUserId(quantBotDetailDTO.getUserId());
                dto.setStrategyType(Integer.valueOf(quantBotDetailDTO.getStrategyType()));
                dto.setCoverTime(Integer.valueOf(quantBotDetailDTO.getCurrentAddCount()));
                dto.setAntiCoverTime(Integer.valueOf(quantBotDetailDTO.getCurrentAntiAddCount()));
                dto.setFloatProfit(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(new BigDecimal(quantBotDetailDTO.getPositionNum())).multiply(currentRate).setScale(8, BigDecimal.ROUND_DOWN));
                dto.setRate(currentRate.multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                dto.setDirection(value.getDirection());
                dto.setLeverRate(value.getLeverRate());
                dto.setLock(quantBotDetailDTO.getLock());
                dto.setExchangeType(Integer.valueOf(quantBotDetailDTO.getExchangeType()));
                dto.setOffSetAmount(getOffSetAmount(dto.getExchangeType(), dto.getDirection().equals(PositionSideTypeEnum.BUY.getCode()) ? PositionSideTypeEnum.SELL.getCode() : PositionSideTypeEnum.BUY.getCode(),
                        dto.getLeverRate(), dto.getDestinationCoin(), dto.getSourceCoin(), dto.getUserId()));

                todayFloatProfit = todayFloatProfit.add(dto.getFloatProfit());
                totalFloatProfit = totalFloatProfit.add(dto.getFloatProfit());

                //-1查询全部
                if (openQuantBotReqDTO.getStrategyType().equals(-1)) {
                    dtos.add(dto);
                } else if (openQuantBotReqDTO.getStrategyType().equals(Integer.valueOf(quantBotDetailDTO.getStrategyType()))) {
                    dtos.add(dto);
                }
            }
        }

        BigDecimal balance = iExchangeOperateService.getTotalAvaliableMoney(openQuantBotReqDTO.getExchangeType(), openQuantBotReqDTO.getUserId(), ValuationAssetTypeEnum.USD.getCode());
        List<OpenQuantBotRespVO> openQuanBotRespVOS = ConvertUtils.convert(dtos, OpenQuantBotRespVO.class);
        userQuantBotRespVO.setList(openQuanBotRespVOS);
        userQuantBotRespVO.setBalance(balance.setScale(4, BigDecimal.ROUND_DOWN));
        userQuantBotRespVO.setTodayFloatProfit(todayFloatProfit);
        userQuantBotRespVO.setTotalFloatProfit(totalFloatProfit);
        userQuantBotRespVO.setTodayFee(todayFee);
        userQuantBotRespVO.setTotalFee(totalFee);
        String buy = stringRedisTemplate.opsForValue().get(RedisConstants.BUY_STOP_LOSS_NUM);
        String sell = stringRedisTemplate.opsForValue().get(RedisConstants.SELL_STOP_LOSS_NUM);
        Integer currentBuyStopLossNum = StringUtils.isEmpty(buy) ? 0 : Integer.valueOf(buy);
        Integer currentSellStopLossNum = StringUtils.isEmpty(sell) ? 0 : Integer.valueOf(sell);
        userQuantBotRespVO.setCurrentBuyStopLossNum(currentBuyStopLossNum);
        userQuantBotRespVO.setCurrentSellStopLossNum(currentSellStopLossNum);
        userQuantBotRespVO.setBuyStopLossLimit(Integer.valueOf(dataDictionaryConfig.getCodeToNameMap().get(DataDictionaryTypeEnum.buy_stop_loss_limit.getCode())));
        userQuantBotRespVO.setSellStopLossLimit(Integer.valueOf(dataDictionaryConfig.getCodeToNameMap().get(DataDictionaryTypeEnum.sell_stop_loss_limit.getCode())));

        return userQuantBotRespVO;
    }

    /**
     * 获取已开启量化的交易对详情
     *
     * @param openQuantBotDetailReqDTO
     * @return
     */
    public OpenQuantBotDetailRespDTO getOpeningQuantBotDetail(OpenQuantBotDetailReqDTO openQuantBotDetailReqDTO) {
        BigDecimal mul = new BigDecimal("100");

        CoinExchangeSet usingCoinExchangeSet = getUsingCoinExchangeSet(openQuantBotDetailReqDTO.getUserId(), openQuantBotDetailReqDTO.getExchangeType(),
                openQuantBotDetailReqDTO.getDestinationCoin(), openQuantBotDetailReqDTO.getSourceCoin(), openQuantBotDetailReqDTO.getDirection());

        openQuantBotDetailReqDTO.setLeverRate(usingCoinExchangeSet.getLeverRate());

        String contractCode = KeyContactUtil.getContractCode(openQuantBotDetailReqDTO.getExchangeType(), openQuantBotDetailReqDTO.getDestinationCoin(),
                openQuantBotDetailReqDTO.getSourceCoin());

        String userBotKey = KeyContactUtil.getUserBotKey(openQuantBotDetailReqDTO.getExchangeType(), openQuantBotDetailReqDTO.getDirection(), openQuantBotDetailReqDTO.getLeverRate(),
                openQuantBotDetailReqDTO.getDestinationCoin(), openQuantBotDetailReqDTO.getSourceCoin(), openQuantBotDetailReqDTO.getUserId());

        //找到该机器人
        QuantBotDetailDTO quantBotDetailDTO = JSONObject.parseObject(stringRedisTemplate.opsForValue().get(userBotKey), QuantBotDetailDTO.class);

        OpenQuantBotDetailRespDTO dto = new OpenQuantBotDetailRespDTO();

        //设置交易所类型
        dto.setExchangeType(openQuantBotDetailReqDTO.getExchangeType());
        //如果是尚未开启的交易对
        if (quantBotDetailDTO == null || quantBotDetailDTO.getStatus().equals(UserBotStatusTypeEnum.STOP.getCode())) {
            dto.setMakeOrderNum(BigDecimal.ZERO);
            dto.setPositionPrice(BigDecimal.ZERO);
            dto.setContractCode(contractCode);
            dto.setDestinationCoin(openQuantBotDetailReqDTO.getDestinationCoin());
            dto.setSourceCoin(openQuantBotDetailReqDTO.getSourceCoin());
            dto.setRate(BigDecimal.ZERO);
            dto.setAmount(BigDecimal.ZERO);
            dto.setUserId(openQuantBotDetailReqDTO.getUserId());
            dto.setStrategyType(Integer.valueOf(TradeStrategyTypeEnum.CIRCLE.getCode()));
            dto.setCoverTime(0);
            dto.setPrice(BigDecimal.ZERO);
            dto.setCoverPirce(BigDecimal.ZERO);
            dto.setInitOrderPosition(usingCoinExchangeSet.getInitOrderPosition());
            dto.setStopProfitRatio(usingCoinExchangeSet.getStopProfitRatio().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setDoubleLimit(usingCoinExchangeSet.getMakeOrderNum());
            dto.setCoverRate(usingCoinExchangeSet.getAddPosition1().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setStopProfitBackRatio(usingCoinExchangeSet.getStopProfitBackRatio().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setAddPositionBackRatio(usingCoinExchangeSet.getAddPositionBackRatio().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setStopLossesRatio(usingCoinExchangeSet.getStopLossesRatio().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setStopLossProfit(usingCoinExchangeSet.getStopLossProfit().multiply(mul));
            dto.setStopProfitPrice(BigDecimal.ZERO);
            dto.setAddPositionTimesModelSwitch(usingCoinExchangeSet.getAddPositionTimesModelSwitch());
            dto.setAddPositionDynamicTimes(usingCoinExchangeSet.getAddPositionDynamicTimes());
            dto.setAddPositionFixTimes(usingCoinExchangeSet.getAddPositionFixTimes());
            dto.setAntiAddPositionTimesModelSwitch(usingCoinExchangeSet.getAntiAddPositionTimesModelSwitch());
            dto.setAntiAddPositionDynamicTimes(usingCoinExchangeSet.getAntiAddPositionDynamicTimes());
            dto.setAntiAddPositionFixTimes(usingCoinExchangeSet.getAntiAddPositionFixTimes());
            dto.setBuyStopRate(usingCoinExchangeSet.getBuyStopRate().multiply(mul));
            dto.setSellStopRate(usingCoinExchangeSet.getSellStopRate().multiply(mul));
            dto.setGetOffAddPositionNum(usingCoinExchangeSet.getGetOffAddPositionNum());
            dto.setGetOffNeedTime(usingCoinExchangeSet.getGetOffNeedTime());
            dto.setGetOffProfitLine(usingCoinExchangeSet.getGetOffProfitLine());
            dto.setTotalStopLossNumLimitAddNum(usingCoinExchangeSet.getTotalStopLossNumLimitAddNum());
            dto.setDirection(openQuantBotDetailReqDTO.getDirection());
            dto.setLeverRate(openQuantBotDetailReqDTO.getLeverRate());
            dto.setStatus(UserBotStatusTypeEnum.STOP.getCode());
            dto.setLock(quantBotDetailDTO == null ? false : quantBotDetailDTO.getLock());
            dto.setOffSetAmount(getOffSetAmount(dto.getExchangeType(), dto.getDirection().equals(PositionSideTypeEnum.BUY.getCode()) ? PositionSideTypeEnum.SELL.getCode() : PositionSideTypeEnum.BUY.getCode(),
                    dto.getLeverRate(), dto.getDestinationCoin(), dto.getSourceCoin(), dto.getUserId()));

            dto.setAntiStopProfitRatio(usingCoinExchangeSet.getAntiStopProfitRatio().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition1().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setAntiCoverTime(0);
            dto.setAntiDoubleLimit(usingCoinExchangeSet.getAntiMakeOrderNum());

        } else if (quantBotDetailDTO.getStatus().equals(UserBotStatusTypeEnum.ACTIVE.getCode())) {
            //用机器人中的卖盘涨幅作为涨幅
            BigDecimal currentRate = new BigDecimal(quantBotDetailDTO.getAskRise());

            dto.setAntiStopProfitRatio(new BigDecimal(quantBotDetailDTO.getAntiStopProfitRatio()).multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setAntiCoverTime(Integer.valueOf(quantBotDetailDTO.getCurrentAntiAddCount()));
            dto.setAntiDoubleLimit(Integer.valueOf(quantBotDetailDTO.getAntiAddCount()));
            Integer antiCoverTime = dto.getAntiCoverTime();
            switch (antiCoverTime) {
                case 0:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition1().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 1:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition2().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 2:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition3().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 3:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition4().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 4:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition5().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 5:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition6().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 6:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition7().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 7:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition8().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 8:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition9().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 9:
                    dto.setAntiCoverRate(usingCoinExchangeSet.getAntiAddPosition10().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
            }

            dto.setContractCode(contractCode);
            dto.setDestinationCoin(openQuantBotDetailReqDTO.getDestinationCoin());
            dto.setSourceCoin(openQuantBotDetailReqDTO.getSourceCoin());
            dto.setRate(currentRate.multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setAmount(new BigDecimal(quantBotDetailDTO.getPositionNum()).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setUserId(openQuantBotDetailReqDTO.getUserId());
            dto.setStrategyType(Integer.valueOf(quantBotDetailDTO.getStrategyType()));
            dto.setCoverTime(Integer.valueOf(quantBotDetailDTO.getCurrentAddCount()));
            switch (quantBotDetailDTO.getCurrentAddCount()) {
                case "0":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio1()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio1()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "1":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio2()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio2()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "2":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio3()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio3()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "3":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio4()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio4()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "4":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio5()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio5()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "5":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio6()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio6()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "6":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio7()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio7()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "7":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio8()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio8()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "8":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio9()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio9()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "9":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio10()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio10()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "10":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio11()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio11()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "11":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio12()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio12()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "12":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio13()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio13()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "13":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio14()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio14()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "14":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio15()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio15()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "15":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio16()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio16()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "16":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio17()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio17()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "17":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio18()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio18()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "18":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio19()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio19()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                case "19":
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio20()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio20()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
                default:
                    if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio20()))).setScale(8, BigDecimal.ROUND_DOWN));
                    } else {
                        dto.setCoverPirce(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                                new BigDecimal(quantBotDetailDTO.getAddPositionRatio20()))).setScale(8, BigDecimal.ROUND_DOWN));
                    }
                    break;
            }
            dto.setPositionPrice(new BigDecimal(quantBotDetailDTO.getAvgPrice()).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setMakeOrderNum(new BigDecimal(quantBotDetailDTO.getPositionAmount()).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setStopLossesRatio(new BigDecimal(quantBotDetailDTO.getStopLossesRatio()).multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setStopLossProfit(new BigDecimal(quantBotDetailDTO.getStopLossProfit()).multiply(mul));
            dto.setAddPositionTimesModelSwitch(quantBotDetailDTO.getAddPositionTimesModelSwitch());
            dto.setAddPositionDynamicTimes(quantBotDetailDTO.getAddPositionDynamicTimes());
            dto.setAddPositionFixTimes(quantBotDetailDTO.getAddPositionFixTimes());
            dto.setAntiAddPositionTimesModelSwitch(quantBotDetailDTO.getAntiAddPositionTimesModelSwitch());
            dto.setAntiAddPositionDynamicTimes(quantBotDetailDTO.getAntiAddPositionDynamicTimes());
            dto.setAntiAddPositionFixTimes(quantBotDetailDTO.getAntiAddPositionFixTimes());
            if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
                //dto.setPrice(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(currentRate)));
                dto.setStopProfitPrice(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.add(
                        new BigDecimal(quantBotDetailDTO.getStopProfitRatio()))).setScale(8, BigDecimal.ROUND_DOWN));
            } else {
                //dto.setPrice(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(currentRate)));
                dto.setStopProfitPrice(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(BigDecimal.ONE.subtract(
                        new BigDecimal(quantBotDetailDTO.getStopProfitRatio()))).setScale(8, BigDecimal.ROUND_DOWN));
            }
            dto.setPrice(new BigDecimal(quantBotDetailDTO.getCurrentBidPrice()));

            dto.setInitOrderPosition(new BigDecimal(quantBotDetailDTO.getInitOrderPosition()));
            dto.setStopProfitRatio(new BigDecimal(quantBotDetailDTO.getStopProfitRatio()).multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setStatus(quantBotDetailDTO.getStatus());
            Integer coverTime = dto.getCoverTime();
            switch (coverTime) {
                case 0:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition1().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 1:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition2().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 2:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition3().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 3:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition4().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 4:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition5().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 5:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition6().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 6:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition7().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 7:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition8().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 8:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition9().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 9:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition10().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 10:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition11().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 11:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition12().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 12:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition13().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 13:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition14().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 14:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition15().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 15:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition16().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 16:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition17().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 17:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition18().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 18:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition19().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 19:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition20().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
                case 20:
                    dto.setCoverRate(usingCoinExchangeSet.getAddPosition20().multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                    break;
            }
            dto.setDoubleLimit(Integer.valueOf(quantBotDetailDTO.getAddCount()));
            dto.setStopProfitBackRatio(new BigDecimal(quantBotDetailDTO.getStopProfitBackRatio()).multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setAddPositionBackRatio(new BigDecimal(quantBotDetailDTO.getAddPositionBackRatio()).multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
            dto.setDirection(openQuantBotDetailReqDTO.getDirection());
            dto.setLeverRate(openQuantBotDetailReqDTO.getLeverRate());
            dto.setLock(quantBotDetailDTO.getLock());
            dto.setBuyStopRate(new BigDecimal(quantBotDetailDTO.getBuyStopRate()).multiply(mul));
            dto.setSellStopRate(new BigDecimal(quantBotDetailDTO.getSellStopRate()).multiply(mul));
            dto.setGetOffAddPositionNum(Integer.valueOf(quantBotDetailDTO.getGetOffAddPositionNum()));
            dto.setGetOffNeedTime(new BigDecimal(quantBotDetailDTO.getGetOffNeedTime()));
            dto.setGetOffProfitLine(new BigDecimal(quantBotDetailDTO.getGetOffProfitLine()));
            dto.setTotalStopLossNumLimitAddNum(Integer.valueOf(quantBotDetailDTO.getTotalStopLossNumLimitAddNum()));
            dto.setOffSetAmount(getOffSetAmount(dto.getExchangeType(), dto.getDirection().equals(PositionSideTypeEnum.BUY.getCode()) ? PositionSideTypeEnum.SELL.getCode() : PositionSideTypeEnum.BUY.getCode(),
                    dto.getLeverRate(), dto.getDestinationCoin(), dto.getSourceCoin(), dto.getUserId()));
        } else {
            log.error(">>> 量化的交易对详情数据错误，请排查 <<<");
            throw new BaseBizException(ResponseStatusEnum.USER_ACCOUNT_EXCEPTION_FOR_SENDXD_ERROR);
        }

        dto.setUid(OrderNoGenerate.getOrderIdByTime());

        return dto;
    }

    /**
     * 获取全部的交易对列表
     *
     * @param getSysOpeningQuantBotListReqDTO
     * @return
     */
    @Override
    public List<GetSysOpeningQuantBotListRespDTO> getSysOpeningQuantBotList(GetSysOpeningQuantBotListReqDTO getSysOpeningQuantBotListReqDTO) {
        BigDecimal mul = new BigDecimal("100");

        //找到某人正在运行中的机器人
        List<UserBot> userBots = userBotMapperExt.selectBotsByUserId(Integer.valueOf(UserBotStatusTypeEnum.ACTIVE.getCode()), getSysOpeningQuantBotListReqDTO.getUserId(),
                getSysOpeningQuantBotListReqDTO.getExchangeType());

        List<GetSysOpeningQuantBotListRespDTO> dtos = new ArrayList<>();

        List<CoinList> coinList = coinListMapperExt.queryCoinListByExchangeType(getSysOpeningQuantBotListReqDTO.getExchangeType(), CoinListStatusTypeEnum.OPEN.code);
        Map<String, String> collectUrlMap = coinList.stream().collect(Collectors.toMap(CoinList::getCollectUrlMapKey, CoinList::getUrl));
        userBots.forEach((value) -> {
            String userBotKey = KeyContactUtil.getUserBotKey(value.getExchangeType(), value.getDirection(), value.getLeverRate(), value.getDestinationCoin(),
                    value.getSourceCoin(), value.getUserId());

            QuantBotDetailDTO quantBotDetailDTO = JSONObject.parseObject(stringRedisTemplate.opsForValue().get(userBotKey), QuantBotDetailDTO.class);
            //用机器人中的卖盘涨幅作为涨幅
            BigDecimal currentRate = new BigDecimal(quantBotDetailDTO.getAskRise());

            GetSysOpeningQuantBotListRespDTO dto = new GetSysOpeningQuantBotListRespDTO();
            //已开启
            if (quantBotDetailDTO.getStatus().equals(UserBotStatusTypeEnum.ACTIVE.getCode())) {
                dto.setId(StringUtils.getRandomNumber(8));
                dto.setSelect(false);
                dto.setContractCode(quantBotDetailDTO.getContractCode());
                dto.setUrl(collectUrlMap.get(KeyContactUtil.getCollectUrlMapKey(value.getDestinationCoin(), value.getDirection())));
                dto.setSourceCoin(value.getSourceCoin());
                dto.setDestinationCoin(value.getDestinationCoin());
                dto.setAmount(new BigDecimal(quantBotDetailDTO.getPositionNum()).setScale(8, BigDecimal.ROUND_DOWN));
                dto.setUserId(quantBotDetailDTO.getUserId());
                dto.setStrategyType(Integer.valueOf(quantBotDetailDTO.getStrategyType()));
                dto.setCoverTime(Integer.valueOf(quantBotDetailDTO.getCurrentAddCount()));
                dto.setAntiCoverTime(Integer.valueOf(quantBotDetailDTO.getCurrentAntiAddCount()));
                dto.setFloatProfit(new BigDecimal(quantBotDetailDTO.getAvgPrice()).multiply(new BigDecimal(quantBotDetailDTO.getPositionNum())).multiply(currentRate).setScale(8, BigDecimal.ROUND_DOWN));
                dto.setRate(currentRate.multiply(mul).setScale(8, BigDecimal.ROUND_DOWN));
                dto.setDirection(quantBotDetailDTO.getDirection());
                dto.setLeverRate(Integer.valueOf(quantBotDetailDTO.getLeverRate()));
                dto.setLock(quantBotDetailDTO.getLock());
                dto.setExchangeType(Integer.valueOf(quantBotDetailDTO.getExchangeType()));
                dto.setOffSetAmount(getOffSetAmount(dto.getExchangeType(), dto.getDirection().equals(PositionSideTypeEnum.BUY.getCode()) ? PositionSideTypeEnum.SELL.getCode() : PositionSideTypeEnum.BUY.getCode(),
                        dto.getLeverRate(), dto.getDestinationCoin(), dto.getSourceCoin(), dto.getUserId()));
                dtos.add(dto);
            }
        });

        coinList.forEach(c -> {
            if (dtos.stream().anyMatch(a -> (KeyContactUtil.getUserBotKey(a.getExchangeType(), a.getDirection(), a.getLeverRate(), a.getDestinationCoin(), a.getSourceCoin(), a.getUserId())).
                    equals(KeyContactUtil.getUserBotKey(c.getExchangeType(), c.getDirection(), a.getLeverRate(), c.getDestinationCoin(), c.getSourceCoin(), a.getUserId())))) {
                return;
            }
            GetSysOpeningQuantBotListRespDTO dto = new GetSysOpeningQuantBotListRespDTO();

            CoinExchangeSet usingCoinExchangeSet = getUsingCoinExchangeSet(getSysOpeningQuantBotListReqDTO.getUserId(), getSysOpeningQuantBotListReqDTO.getExchangeType(),
                    c.getDestinationCoin(), c.getSourceCoin(), c.getDirection());

            dto.setId(StringUtils.getRandomNumber(8));
            dto.setSelect(false);
            dto.setLeverRate(usingCoinExchangeSet.getLeverRate());
            dto.setContractCode(KeyContactUtil.getContractCode(c.getExchangeType(), c.getDestinationCoin(), c.getSourceCoin()));
            dto.setSourceCoin(c.getSourceCoin());
            dto.setDestinationCoin(c.getDestinationCoin());
            dto.setRate(BigDecimal.ZERO);
            dto.setAmount(BigDecimal.ZERO);
            dto.setUserId(getSysOpeningQuantBotListReqDTO.getUserId());
            dto.setStrategyType(Integer.valueOf(TradeStrategyTypeEnum.CIRCLE.getCode()));
            dto.setCoverTime(0);
            dto.setAntiCoverTime(0);
            dto.setUrl(collectUrlMap.get(c.getCollectUrlMapKey()));
            dto.setFloatProfit(BigDecimal.ZERO);
            dto.setDirection(c.getDirection());
            dto.setExchangeType(c.getExchangeType());
            dto.setOffSetAmount(getOffSetAmount(dto.getExchangeType(), dto.getDirection().equals(PositionSideTypeEnum.BUY.getCode()) ? PositionSideTypeEnum.SELL.getCode() : PositionSideTypeEnum.BUY.getCode(),
                    dto.getLeverRate(), dto.getDestinationCoin(), dto.getSourceCoin(), dto.getUserId()));
            dtos.add(dto);
        });
        return dtos;
    }

    /**
     * 设置当前止损次数
     *
     * @param setStopLossNumReqDTO
     * @return
     */
    @Override
    public SetStopLossNumRespDTO setStopLossNum(SetStopLossNumReqDTO setStopLossNumReqDTO) {
        if (setStopLossNumReqDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
            stringRedisTemplate.opsForValue().set(RedisConstants.BUY_STOP_LOSS_NUM, String.valueOf(setStopLossNumReqDTO.getStopLossNum()));
        } else if (setStopLossNumReqDTO.getDirection().equals(PositionSideTypeEnum.SELL.getCode())) {
            stringRedisTemplate.opsForValue().set(RedisConstants.SELL_STOP_LOSS_NUM, String.valueOf(setStopLossNumReqDTO.getStopLossNum()));
        } else {
            throw new BaseBizException(ResponseStatusEnum.ROBOT_DIRECTION_NOT_EXIST);
        }
        String buy = stringRedisTemplate.opsForValue().get(RedisConstants.BUY_STOP_LOSS_NUM);
        String sell = stringRedisTemplate.opsForValue().get(RedisConstants.SELL_STOP_LOSS_NUM);

        Integer currentBuyStopLossNum = StringUtils.isEmpty(buy) ? 0 : Integer.valueOf(buy);
        Integer currentSellStopLossNum = StringUtils.isEmpty(sell) ? 0 : Integer.valueOf(sell);

        SetStopLossNumRespDTO setStopLossNumRespDTO = new SetStopLossNumRespDTO();
        setStopLossNumRespDTO.setCurrentBuyStopLossNum(currentBuyStopLossNum);
        setStopLossNumRespDTO.setCurrentSellStopLossNum(currentSellStopLossNum);

        return setStopLossNumRespDTO;
    }

    @Override
    public GetSmallestInitOrderPositionRespDTO getSmallestInitOrderPosition(GetSmallestInitOrderPositionReqDTO getSmallestInitOrderPositionReqDTO) {
        BigDecimal appearMarketPrice = iExchangeOperateService.getAppearMarketPrice(getSmallestInitOrderPositionReqDTO.getExchangeType(), getSmallestInitOrderPositionReqDTO.getUserId(),
                getSmallestInitOrderPositionReqDTO.getDestinationCoin(), getSmallestInitOrderPositionReqDTO.getSourceCoin());
        CoinList coinList = coinListMapperExt.queryCoinListByDestinationCoinAndSourceCoin(
                getSmallestInitOrderPositionReqDTO.getExchangeType(),
                getSmallestInitOrderPositionReqDTO.getDestinationCoin(),
                getSmallestInitOrderPositionReqDTO.getSourceCoin(),
                CoinListStatusTypeEnum.OPEN.code,
                getSmallestInitOrderPositionReqDTO.getDirection());

        BigDecimal smallCoinAmount = coinList.getDecimal();

        //防止卡在边界值，所以加1U
        BigDecimal smallestInitOrderPosition = appearMarketPrice.multiply(smallCoinAmount).add(BigDecimal.ONE).setScale(0, RoundingMode.CEILING);

        GetSmallestInitOrderPositionRespDTO getSmallestInitOrderPositionRespDTO = new GetSmallestInitOrderPositionRespDTO();
        getSmallestInitOrderPositionRespDTO.setSmallestInitOrderPosition(smallestInitOrderPosition);

        return getSmallestInitOrderPositionRespDTO;
    }

    /**
     * 控制操作频率，避免并发多次重复提交
     *
     * @param key
     * @return
     */
    private void checkOperateSubmitFrequency(String key) {
        if (null != redisTemplate.opsForValue().get(RedisConstants.QUANT_OPERATE_FREQUENCY_CACHE + key)) {
            log.error(">>> 控制交易频率异常（在一秒内多次重复提交测试）<<<");
            throw new BaseBizException(ResponseStatusEnum.REPEAT_RESUBMIT);
        }
        redisTemplate.opsForValue().set(RedisConstants.QUANT_OPERATE_FREQUENCY_CACHE + key, key);
        redisTemplate.expire(RedisConstants.QUANT_OPERATE_FREQUENCY_CACHE + key, 1, TimeUnit.SECONDS);
    }

    /**
     * 控制查询频率，避免并发多次重复提交
     *
     * @param key
     * @return
     */
    private void checkQueryRequency(String key) {
        if (null != redisTemplate.opsForValue().get(key)) {
            log.error(">>> 控制查询频率异常（在一秒内多次重复提交测试）<<<");
            throw new BaseBizException(ResponseStatusEnum.REPEAT_RESUBMIT);
        }
        redisTemplate.opsForValue().set(key, key);
        redisTemplate.expire(key, 1, TimeUnit.SECONDS);
    }

    private OperateBotRespDTO toExecuteOperate(OperateBotReqDTO operateBotReqDTO, QuantBotDetailDTO quantBotDetailDTO, String userBotKey) {
        OperateBotRespDTO operateBotRespDTO = null;
        if (operateBotReqDTO.getOperateType() == OperateTypeEnum.SELL.getCode()) {
            //清仓
            operateBotRespDTO = toDoSell(operateBotReqDTO, quantBotDetailDTO, userBotKey);
        } else if (operateBotReqDTO.getOperateType() == OperateTypeEnum.BUY.getCode()) {
            //先判断该机器人是否暂停，如果是暂停状态，则更新redis和数据库的开启状态返回即可;如果不是，则执行买逻辑
            if (quantBotDetailDTO != null && quantBotDetailDTO.getStatus().equals(UserBotStatusTypeEnum.STOP.getCode())) {
                //激活机器人
                operateBotRespDTO = toChangeBotStatus(operateBotReqDTO, quantBotDetailDTO, userBotKey, UserBotStatusTypeEnum.ACTIVE.getCode());
            } else {
                //开仓
                operateBotRespDTO = toDoBuy(operateBotReqDTO, quantBotDetailDTO, userBotKey);
            }
        } else if (operateBotReqDTO.getOperateType() == OperateTypeEnum.STOP_BOT.getCode()) {
            //暂停机器人
            operateBotRespDTO = toChangeBotStatus(operateBotReqDTO, quantBotDetailDTO, userBotKey, UserBotStatusTypeEnum.STOP.getCode());
        } else if (operateBotReqDTO.getOperateType() == OperateTypeEnum.LOCK.getCode()) {
            //锁仓
            toDoLock(operateBotReqDTO, quantBotDetailDTO, userBotKey);
        } else if (operateBotReqDTO.getOperateType() == OperateTypeEnum.UNLOCK.getCode()) {
            //解锁
            toDoUnLock(operateBotReqDTO, quantBotDetailDTO, userBotKey);
        } else {
            throw new BaseBizException(ResponseStatusEnum.OPERATE_TYPE_ERROR);
        }

        return operateBotRespDTO;
    }

    private OperateBotRespDTO toDoBuy(OperateBotReqDTO operateBotReqDTO, QuantBotDetailDTO quantBotDetailDTO, String userBotKey) {
        //校验杠杆倍数是否可用
        boolean leverRateCanUse = iExchangeOperateService.leverRateCanUse(operateBotReqDTO.getExchangeType(), operateBotReqDTO.getUserId(), operateBotReqDTO.getDestinationCoin(),
                operateBotReqDTO.getSourceCoin(), operateBotReqDTO.getLeverRate());
        if (!leverRateCanUse) {
            throw new BaseBizException(ResponseStatusEnum.ERROR_LEVERRATE);
        }

        //校验用户点卡是否足够
        UserWalletInfo userWalletInfo = new UserWalletInfo();
        userWalletInfo.setUserId(operateBotReqDTO.getUserId());
        userWalletInfo.setChainName(ChainTypeEnum.TRON.getCode());
        userWalletInfo.setCoinName(CoinTypeEnum.USDT.getCode());
        UserWalletInfo walletInfo = userWalletInfoMapperExt.selectOne(userWalletInfo);
        BigDecimal pointMin = new BigDecimal(dataDictionaryConfig.getCodeToNameMap().get(
                DataDictionaryTypeEnum.start_robot_point_balance_min.getCode()));
        if (walletInfo.getPointBalance().compareTo(pointMin) < 0) {
            throw new BaseBizException(ResponseStatusEnum.WALLET_BALANCE_NOT_ENOUGH);
        }

        //先获取可开数
        BigDecimal avaliablePieces = iExchangeOperateService.getAvaliablePieces(operateBotReqDTO.getExchangeType(), operateBotReqDTO.getUserId(),
                operateBotReqDTO.getDestinationCoin(), operateBotReqDTO.getSourceCoin(), operateBotReqDTO.getDirection(), operateBotReqDTO.getLeverRate());

        //判断可开数是否足够
        if (avaliablePieces.compareTo(operateBotReqDTO.getAmount()) < 0) {
            throw new BaseBizException(ResponseStatusEnum.AVAILABLE_OPEN_AMOUNT_NOT_ENOUGH);
        }

        //交易对是否已经开了量化
        if (null != quantBotDetailDTO && quantBotDetailDTO.getStatus().equals(UserBotStatusTypeEnum.ACTIVE.getCode())) {
            throw new BaseBizException(ResponseStatusEnum.QUAN_BOT_ALREADY_OPEN_ERROR);
        }

        boolean changeLeverResult = iExchangeOperateService.changeLeverRate(operateBotReqDTO.getExchangeType(), operateBotReqDTO.getUserId(),
                operateBotReqDTO.getDestinationCoin(), operateBotReqDTO.getSourceCoin(), operateBotReqDTO.getLeverRate());
        if (!changeLeverResult) {
            throw new BaseBizException(ResponseStatusEnum.CHANGE_LEVERRATE_ERROR);
        }

        Long exchangeOrderId = toExecuteBuyOrder(operateBotReqDTO, userBotKey, operateBotReqDTO.getAmount());

        OperateBotRespDTO operateBotRespDTO = new OperateBotRespDTO();
        operateBotRespDTO.setOrderId(exchangeOrderId);

        return operateBotRespDTO;
    }

    private OperateBotRespDTO toDoSell(OperateBotReqDTO operateBotReqDTO, QuantBotDetailDTO quantBotDetailDTO, String userBotKey) {
        //清仓需要已开启
        if (quantBotDetailDTO == null) {
            throw new BaseBizException(ResponseStatusEnum.QUAN_BOT_NOT_EXIST_ERROR);
        }

        UserBot userBot = userBotMapperExt.selectByUserIdAndCoinAndDirectionAdnLever(quantBotDetailDTO.getUserId(),
                quantBotDetailDTO.getDestinationCoin(),
                quantBotDetailDTO.getSourceCoin(),
                quantBotDetailDTO.getDirection(),
                Integer.valueOf(quantBotDetailDTO.getLeverRate()),
                Integer.valueOf(quantBotDetailDTO.getExchangeType()));

        //清仓需要关闭机器人
        if (userBot.getStatus().equals(UserBotStatusTypeEnum.ACTIVE.getCode())) {
            throw new BaseBizException(ResponseStatusEnum.QUAN_BOT_MUST_CLOSED);
        }

        //清仓时不能有锁仓
        if (quantBotDetailDTO.getLock()) {
            throw new BaseBizException(ResponseStatusEnum.QUANT_BOT_IN_LOCK);
        }

        OperateBotRespDTO operateBotRespDTO = new OperateBotRespDTO();

        //如果是清仓操作，需要更新redis机器人，user_bot机器人表要更新
        Long exchangeOrderId = toExecuteSellOrder(operateBotReqDTO, userBotKey, quantBotDetailDTO);

        operateBotRespDTO.setOrderId(exchangeOrderId);

        return operateBotRespDTO;
    }

    private OperateBotRespDTO toChangeBotStatus(OperateBotReqDTO operateBotReqDTO, QuantBotDetailDTO quantBotDetailDTO, String userBotKey, String userBotStatus) {
        //设置机器人状态
        quantBotDetailDTO.setStatus(userBotStatus);

        //更新数据库机器人
        int i = userBotMapperExt.updateByUserIdAndCoin(operateBotReqDTO.getUserId(), operateBotReqDTO.getDestinationCoin(), operateBotReqDTO.getSourceCoin(),
                Integer.valueOf(userBotStatus), operateBotReqDTO.getDirection(), operateBotReqDTO.getLeverRate(), operateBotReqDTO.getExchangeType());
        if (i < 1) {
            throw new BaseBizException(ResponseStatusEnum.ERROR);
        }

        //更新redis机器人
        stringRedisTemplate.opsForValue().set(userBotKey, JSON.toJSONString(quantBotDetailDTO));

        OperateBotRespDTO operateBotRespDTO = new OperateBotRespDTO();
        operateBotRespDTO.setOrderId(-1L);
        return operateBotRespDTO;
    }

    private void toDoLock(OperateBotReqDTO operateBotReqDTO, QuantBotDetailDTO quantBotDetailDTO, String userBotKey) {
        //机器人必须已经开启
        if (quantBotDetailDTO == null) {
            throw new BaseBizException(ResponseStatusEnum.QUAN_BOT_NOT_EXIST_ERROR);
        }

        //不能重复锁仓
        if (quantBotDetailDTO.getLock()) {
            throw new BaseBizException(ResponseStatusEnum.QUANT_BOT_IN_LOCK);
        }

        //开仓对冲单
        operateBotReqDTO.setOperateType(OperateTypeEnum.BUY.getCode());
        operateBotReqDTO.setAmount(new BigDecimal(quantBotDetailDTO.getPositionPiece()));

        //设置开仓方向,与当前持仓方向相反
        if (quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode())) {
            operateBotReqDTO.setDirection(PositionSideTypeEnum.SELL.getCode());
        } else {
            operateBotReqDTO.setDirection(PositionSideTypeEnum.BUY.getCode());
        }

        TradeResponseVO tradeResponseVO = iExchangeOperateService.trade(operateBotReqDTO.getExchangeType(), operateBotReqDTO);

        //获取该对冲单详情
        OrderDetailResponseVO orderDetail = iExchangeOperateService.getOrderDetail(operateBotReqDTO.getExchangeType(), operateBotReqDTO, tradeResponseVO);

        //构造锁仓详情对象
        QuantBotLockDetailDTO quantBotLockDetailDTO = new QuantBotLockDetailDTO();
        quantBotLockDetailDTO.setLockDestinationCoin(operateBotReqDTO.getDestinationCoin());
        quantBotLockDetailDTO.setLockSourceCoin(operateBotReqDTO.getSourceCoin());
        quantBotLockDetailDTO.setLockExchangeType(String.valueOf(operateBotReqDTO.getExchangeType()));
        quantBotLockDetailDTO.setLockContractCode(quantBotDetailDTO.getContractCode());
        quantBotLockDetailDTO.setLockPositionAmount(String.valueOf(orderDetail.getTradeTurnover()));
        quantBotLockDetailDTO.setLockPositionNum(String.valueOf(orderDetail.getTradeVolumeNum()));
        quantBotLockDetailDTO.setLockPositionPiece(String.valueOf(orderDetail.getTradeVolume()));
        quantBotLockDetailDTO.setLockAvgPrice(String.valueOf(orderDetail.getTradeAvgPrice()));
        quantBotLockDetailDTO.setDirection(orderDetail.getDirection());
        quantBotLockDetailDTO.setLeverRate(String.valueOf(orderDetail.getLeverRate()));

        //更新redis中的机器人锁仓详情
        quantBotDetailDTO.setLock(true);
        quantBotDetailDTO.setQuantBotLockDetailDTO(quantBotLockDetailDTO);
        stringRedisTemplate.opsForValue().set(userBotKey, JSON.toJSONString(quantBotDetailDTO));

        //发送消息提醒手动锁仓成功
        userInfoFeignApi.sendEmail(
                new SendEmailReqDTO("UserId:" + operateBotReqDTO.getUserId()
                        + "  交易对:" + operateBotReqDTO.getDestinationCoin().concat(operateBotReqDTO.getSourceCoin())
                        + "  方向:" + operateBotReqDTO.getDirection()
                        + "  倍数:" + operateBotReqDTO.getLeverRate()
                        + "  手动锁仓成功!"));
    }

    private void toDoUnLock(OperateBotReqDTO operateBotReqDTO, QuantBotDetailDTO quantBotDetailDTO, String userBotKey) {
        //机器人必须已经开启
        if (quantBotDetailDTO == null) {
            throw new BaseBizException(ResponseStatusEnum.QUAN_BOT_NOT_EXIST_ERROR);
        }

        //必须处于锁仓状态
        if (!quantBotDetailDTO.getLock()) {
            throw new BaseBizException(ResponseStatusEnum.QUANT_BOT_IN_UNLOCK);
        }

        //清仓对冲单
        operateBotReqDTO.setAmount(new BigDecimal(quantBotDetailDTO.getQuantBotLockDetailDTO().getLockPositionPiece()));
        operateBotReqDTO.setDirection(quantBotDetailDTO.getQuantBotLockDetailDTO().getDirection());
        operateBotReqDTO.setLeverRate(Integer.valueOf(quantBotDetailDTO.getQuantBotLockDetailDTO().getLeverRate()));
        operateBotReqDTO.setOperateType(OperateTypeEnum.SELL.getCode());
        iExchangeOperateService.trade(operateBotReqDTO.getExchangeType(), operateBotReqDTO);

        //更新redis中的机器人锁仓详情
        quantBotDetailDTO.setLock(false);
        quantBotDetailDTO.setQuantBotLockDetailDTO(new QuantBotLockDetailDTO());
        quantBotDetailDTO.setCurrentUnLockNum(String.valueOf(Integer.valueOf(quantBotDetailDTO.getCurrentUnLockNum()) + 1));
        stringRedisTemplate.opsForValue().set(userBotKey, JSON.toJSONString(quantBotDetailDTO));

        //发送消息提醒手动解锁成功
        userInfoFeignApi.sendEmail(
                new SendEmailReqDTO("UserId:" + operateBotReqDTO.getUserId()
                        + "  交易对:" + operateBotReqDTO.getDestinationCoin().concat(operateBotReqDTO.getSourceCoin())
                        + "  方向:" + operateBotReqDTO.getDirection()
                        + "  倍数:" + operateBotReqDTO.getLeverRate()
                        + "  手动解锁成功!"));
    }

    private Long toExecuteBuyOrder(OperateBotReqDTO operateBotReqDTO, String userBotKey, BigDecimal initOrderPosition) {
        //根据交易所设置真实开仓数量
        BigDecimal realAmount = executeOrderServiceImpl.toSetOpenOrderAmount(operateBotReqDTO, operateBotReqDTO.getAmount());
        operateBotReqDTO.setAmount(realAmount);

        QuantBotDetailDTO botDetail = initBotDetail(operateBotReqDTO, initOrderPosition);

        UserBot userBot = userBotMapperExt.selectByUserIdAndCoinAndDirectionAdnLever(operateBotReqDTO.getUserId(), operateBotReqDTO.getDestinationCoin(), operateBotReqDTO.getSourceCoin(),
                operateBotReqDTO.getDirection(), operateBotReqDTO.getLeverRate(), operateBotReqDTO.getExchangeType());

        if (userBot == null) {
            UserBot newUserBot = new UserBot();
            newUserBot.setUserId(operateBotReqDTO.getUserId());
            newUserBot.setStatus(Integer.valueOf(UserBotStatusTypeEnum.ACTIVE.getCode()));
            newUserBot.setDestinationCoin(operateBotReqDTO.getDestinationCoin());
            newUserBot.setSourceCoin(operateBotReqDTO.getSourceCoin());
            newUserBot.setExchangeType(operateBotReqDTO.getExchangeType());
            newUserBot.setDirection(operateBotReqDTO.getDirection());
            newUserBot.setLeverRate(operateBotReqDTO.getLeverRate());
            userBotMapperExt.insertSelective(newUserBot);
        } else {
            int i = userBotMapperExt.updateByUserIdAndCoin(operateBotReqDTO.getUserId(), operateBotReqDTO.getDestinationCoin(), operateBotReqDTO.getSourceCoin(),
                    Integer.valueOf(UserBotStatusTypeEnum.ACTIVE.getCode()), operateBotReqDTO.getDirection(), operateBotReqDTO.getLeverRate(), operateBotReqDTO.getExchangeType());
            if (i < 1) {
                throw new BaseBizException(ResponseStatusEnum.ERROR);
            }
        }

        stringRedisTemplate.opsForValue().set(userBotKey, JSON.toJSONString(botDetail));

        return 0l;
    }

    private Long toExecuteSellOrder(OperateBotReqDTO operateBotReqDTO, String userBotKey, QuantBotDetailDTO quantBotDetailDTO) {
        //查询交易所中该杠杆倍数该多空方向下的该交易对的可用仓位余额
        BigDecimal avaliableClosePosition = iExchangeOperateService.getAvaliablePosition(Integer.valueOf(quantBotDetailDTO.getExchangeType()), quantBotDetailDTO.getUserId(), quantBotDetailDTO.getContractCode(),
                quantBotDetailDTO.getDirection(), Integer.valueOf(quantBotDetailDTO.getLeverRate()));

        //获取方向相反方向的锁仓仓位
        BigDecimal lockPosition = BigDecimal.ZERO;

        //获取方向相反方向机器人对象
        String lockUserBotKey = KeyContactUtil.getUserBotKey(Integer.valueOf(quantBotDetailDTO.getExchangeType()),
                quantBotDetailDTO.getDirection().equals(PositionSideTypeEnum.BUY.getCode()) ? PositionSideTypeEnum.SELL.getCode() : PositionSideTypeEnum.BUY.getCode(),
                Integer.valueOf(quantBotDetailDTO.getLeverRate()), quantBotDetailDTO.getDestinationCoin(), quantBotDetailDTO.getSourceCoin(), quantBotDetailDTO.getUserId());
        QuantBotDetailDTO lockBot = JSONObject.parseObject(stringRedisTemplate.opsForValue().get(lockUserBotKey), QuantBotDetailDTO.class);

        if (lockBot != null) {
            lockPosition = lockBot.getQuantBotLockDetailDTO() == null ? BigDecimal.ZERO : new BigDecimal(lockBot.getQuantBotLockDetailDTO().getLockPositionPiece());
        }

        //减去方向相反的机器人的锁仓仓位,才是真正可平仓的仓位数量
        avaliableClosePosition = avaliableClosePosition.subtract(lockPosition);

        if (avaliableClosePosition.compareTo(BigDecimal.ZERO) <= 0) {
            //清除redis中的机器人
            stringRedisTemplate.delete(userBotKey);
            //throw new BaseBizException(ResponseStatusEnum.POSITION_NOT_EXIST);
            return -1l;
        } else if (new BigDecimal(quantBotDetailDTO.getPositionPiece()).compareTo(BigDecimal.ZERO) <= 0) {
            //清除redis中的机器人
            stringRedisTemplate.delete(userBotKey);
            throw new BaseBizException(ResponseStatusEnum.SELL_AMOUNT_ERROR);
        } else {
            //设置平仓数量
            operateBotReqDTO.setAmount(new BigDecimal(quantBotDetailDTO.getPositionPiece()));

            //清仓所有仓位
            OrderDetailResponseVO orderDetail = executeOrderServiceImpl.chooseSendOrderHttp(operateBotReqDTO, SystemInnerTypeEnum.HAND_CLEAR.code);

            //清除redis中的机器人
            stringRedisTemplate.delete(userBotKey);
            return orderDetail.getOrderId();
        }
    }

    private UpdateStrategyRespDTO toExecuteUpdateStrategy(UpdateStrategyReqDTO dto) {
        UpdateStrategyRespDTO respDTO = new UpdateStrategyRespDTO();

        List<CoinExchangeSet> coinExchangeSets = coinExchangeSetMapperExt.queryCoinExchangeSetByUserIdExchangeTypeCoin(dto.getUserId(), dto.getExchangeType(), dto.getDestinationCoin(), dto.getSourceCoin(), dto.getDirection());
        CoinExchangeSet coinExchangeSet = new CoinExchangeSet();
        ConvertBeanUtil.copyBeanProperties(dto, coinExchangeSet);
        coinExchangeSet.setCreateTime(new Date());
        coinExchangeSet.setModifyTime(new Date());

        if (coinExchangeSets.size() > 0) {
            coinExchangeSet.setId(coinExchangeSets.get(0).getId());

            //更新用户正在运行的机器人
            String userBotKey = KeyContactUtil.getUserBotKey(dto.getExchangeType(), coinExchangeSets.get(0).getDirection(), coinExchangeSets.get(0).getLeverRate(), dto.getDestinationCoin(), dto.getSourceCoin(), dto.getUserId());
            String bot = stringRedisTemplate.opsForValue().get(userBotKey);

            if (StringUtils.isNotEmpty(bot)) {
                QuantBotDetailDTO quantBotDetailDTO = JSONObject.parseObject(bot, QuantBotDetailDTO.class);

                //如果机器人存在,并且正在使用的杠杆倍数和需要更新的杠杆倍数不一致,则不能进行更新
                if (Integer.valueOf(quantBotDetailDTO.getLeverRate()) != dto.getLeverRate()) {
                    throw new BaseBizException(ResponseStatusEnum.LEVERATE_IN_USING);
                }

                quantBotDetailDTO.setInitOrderPosition(dto.getInitOrderPosition().toPlainString());
                quantBotDetailDTO.setAddCount(String.valueOf(dto.getMakeOrderNum()));
                quantBotDetailDTO.setStopProfitRatio(dto.getStopProfitRatio().toPlainString());
                quantBotDetailDTO.setStopProfitBackRatio(dto.getStopProfitBackRatio().toPlainString());
                quantBotDetailDTO.setAddPositionRatio1(String.valueOf(dto.getAddPosition1()));
                quantBotDetailDTO.setAddPositionRatio2(String.valueOf(dto.getAddPosition2()));
                quantBotDetailDTO.setAddPositionRatio3(String.valueOf(dto.getAddPosition3()));
                quantBotDetailDTO.setAddPositionRatio4(String.valueOf(dto.getAddPosition4()));
                quantBotDetailDTO.setAddPositionRatio5(String.valueOf(dto.getAddPosition5()));
                quantBotDetailDTO.setAddPositionRatio6(String.valueOf(dto.getAddPosition6()));
                quantBotDetailDTO.setAddPositionRatio7(String.valueOf(dto.getAddPosition7()));
                quantBotDetailDTO.setAddPositionRatio8(String.valueOf(dto.getAddPosition8()));
                quantBotDetailDTO.setAddPositionRatio9(String.valueOf(dto.getAddPosition9()));
                quantBotDetailDTO.setAddPositionRatio10(String.valueOf(dto.getAddPosition10()));
                quantBotDetailDTO.setAddPositionRatio11(String.valueOf(dto.getAddPosition11()));
                quantBotDetailDTO.setAddPositionRatio12(String.valueOf(dto.getAddPosition12()));
                quantBotDetailDTO.setAddPositionRatio13(String.valueOf(dto.getAddPosition13()));
                quantBotDetailDTO.setAddPositionRatio14(String.valueOf(dto.getAddPosition14()));
                quantBotDetailDTO.setAddPositionRatio15(String.valueOf(dto.getAddPosition15()));
                quantBotDetailDTO.setAddPositionRatio16(String.valueOf(dto.getAddPosition16()));
                quantBotDetailDTO.setAddPositionRatio17(String.valueOf(dto.getAddPosition17()));
                quantBotDetailDTO.setAddPositionRatio18(String.valueOf(dto.getAddPosition18()));
                quantBotDetailDTO.setAddPositionRatio19(String.valueOf(dto.getAddPosition19()));
                quantBotDetailDTO.setAddPositionRatio20(String.valueOf(dto.getAddPosition20()));
                quantBotDetailDTO.setStopLossesRatio(String.valueOf(dto.getStopLossesRatio()));
                quantBotDetailDTO.setStopLossProfit(String.valueOf(dto.getStopLossProfit()));
                quantBotDetailDTO.setAddPositionBackRatio(dto.getAddPositionBackRatio().toPlainString());
                quantBotDetailDTO.setStrategyType(String.valueOf(dto.getStrategyType()));
                quantBotDetailDTO.setAddPositionTimesModelSwitch(dto.getAddPositionTimesModelSwitch());
                quantBotDetailDTO.setAddPositionDynamicTimes(dto.getAddPositionDynamicTimes());
                quantBotDetailDTO.setAddPositionFixTimes(dto.getAddPositionFixTimes());
                quantBotDetailDTO.setAntiAddPositionTimesModelSwitch(dto.getAntiAddPositionTimesModelSwitch());
                quantBotDetailDTO.setAntiAddPositionDynamicTimes(dto.getAntiAddPositionDynamicTimes());
                quantBotDetailDTO.setAntiAddPositionFixTimes(dto.getAntiAddPositionFixTimes());
                quantBotDetailDTO.setBuyStopRate(String.valueOf(dto.getBuyStopRate()));
                quantBotDetailDTO.setSellStopRate(String.valueOf(dto.getSellStopRate()));
                quantBotDetailDTO.setGetOffAddPositionNum(String.valueOf(dto.getGetOffAddPositionNum()));
                quantBotDetailDTO.setGetOffNeedTime(String.valueOf(dto.getGetOffNeedTime()));
                quantBotDetailDTO.setGetOffProfitLine(String.valueOf(dto.getGetOffProfitLine()));
                quantBotDetailDTO.setTotalStopLossNumLimitAddNum(String.valueOf(dto.getTotalStopLossNumLimitAddNum()));
                quantBotDetailDTO.setAntiAddCount(String.valueOf(dto.getAntiMakeOrderNum()));
                quantBotDetailDTO.setAntiStopProfitRatio(dto.getAntiStopProfitRatio().toPlainString());
                quantBotDetailDTO.setAntiAddPositionRatio1(String.valueOf(dto.getAntiAddPosition1()));
                quantBotDetailDTO.setAntiAddPositionRatio2(String.valueOf(dto.getAntiAddPosition2()));
                quantBotDetailDTO.setAntiAddPositionRatio3(String.valueOf(dto.getAntiAddPosition3()));
                quantBotDetailDTO.setAntiAddPositionRatio4(String.valueOf(dto.getAntiAddPosition4()));
                quantBotDetailDTO.setAntiAddPositionRatio5(String.valueOf(dto.getAntiAddPosition5()));
                quantBotDetailDTO.setAntiAddPositionRatio6(String.valueOf(dto.getAntiAddPosition6()));
                quantBotDetailDTO.setAntiAddPositionRatio7(String.valueOf(dto.getAntiAddPosition7()));
                quantBotDetailDTO.setAntiAddPositionRatio8(String.valueOf(dto.getAntiAddPosition8()));
                quantBotDetailDTO.setAntiAddPositionRatio9(String.valueOf(dto.getAntiAddPosition9()));
                quantBotDetailDTO.setAntiAddPositionRatio10(String.valueOf(dto.getAntiAddPosition10()));
                stringRedisTemplate.opsForValue().set(userBotKey, JSON.toJSONString(quantBotDetailDTO));
            }

            //更新设置
            coinExchangeSetMapperExt.updateByPrimaryKey(coinExchangeSet);
        } else {
            //新增
            coinExchangeSetMapperExt.insertSelective(coinExchangeSet);
        }

        respDTO.setUserId(dto.getUserId());
        return respDTO;
    }

    private QuantBotDetailDTO initBotDetail(OperateBotReqDTO dto, BigDecimal initOrderPosition) {
        QuantBotDetailDTO quantBotDetailDTO = new QuantBotDetailDTO();
        CoinList coinList = coinListMapperExt.queryCoinListByDestinationCoinAndSourceCoin(dto.getExchangeType(), dto.getDestinationCoin(), dto.getSourceCoin(), CoinListStatusTypeEnum.OPEN.code,
                dto.getDirection());

        CoinExchangeSet usingCoinExchangeSet = getUsingCoinExchangeSet(dto.getUserId(), dto.getExchangeType(), dto.getDestinationCoin(), dto.getSourceCoin(), dto.getDirection());

        quantBotDetailDTO.setUserId(dto.getUserId());
        quantBotDetailDTO.setDestinationCoin(dto.getDestinationCoin());
        quantBotDetailDTO.setSourceCoin(dto.getSourceCoin());
        quantBotDetailDTO.setExchangeType(String.valueOf(dto.getExchangeType()));
        quantBotDetailDTO.setContractCode(KeyContactUtil.getContractCode(dto.getExchangeType(), dto.getDestinationCoin(), dto.getSourceCoin()));
        quantBotDetailDTO.setContractCodeValue(String.valueOf(coinList.getContractCodeValue()));
        quantBotDetailDTO.setContractCode(KeyContactUtil.getContractCode(dto.getExchangeType(), dto.getDestinationCoin(), dto.getSourceCoin()));
        quantBotDetailDTO.setInitOrderPosition(String.valueOf(initOrderPosition));
        quantBotDetailDTO.setStopProfitRatio(String.valueOf(usingCoinExchangeSet.getStopProfitRatio()));
        quantBotDetailDTO.setStopProfitBackRatio(String.valueOf(usingCoinExchangeSet.getStopProfitBackRatio()));
        quantBotDetailDTO.setAddPositionRatio1(String.valueOf(usingCoinExchangeSet.getAddPosition1().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio2(String.valueOf(usingCoinExchangeSet.getAddPosition2().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio3(String.valueOf(usingCoinExchangeSet.getAddPosition3().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio4(String.valueOf(usingCoinExchangeSet.getAddPosition4().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio5(String.valueOf(usingCoinExchangeSet.getAddPosition5().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio6(String.valueOf(usingCoinExchangeSet.getAddPosition6().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio7(String.valueOf(usingCoinExchangeSet.getAddPosition7().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio8(String.valueOf(usingCoinExchangeSet.getAddPosition8().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio9(String.valueOf(usingCoinExchangeSet.getAddPosition9().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio10(String.valueOf(usingCoinExchangeSet.getAddPosition10().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio11(String.valueOf(usingCoinExchangeSet.getAddPosition11().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio12(String.valueOf(usingCoinExchangeSet.getAddPosition12().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio13(String.valueOf(usingCoinExchangeSet.getAddPosition13().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio14(String.valueOf(usingCoinExchangeSet.getAddPosition14().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio15(String.valueOf(usingCoinExchangeSet.getAddPosition15().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio16(String.valueOf(usingCoinExchangeSet.getAddPosition16().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio17(String.valueOf(usingCoinExchangeSet.getAddPosition17().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio18(String.valueOf(usingCoinExchangeSet.getAddPosition18().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio19(String.valueOf(usingCoinExchangeSet.getAddPosition19().abs().negate()));
        quantBotDetailDTO.setAddPositionRatio20(String.valueOf(usingCoinExchangeSet.getAddPosition20().abs().negate()));
        quantBotDetailDTO.setStopLossesRatio(String.valueOf(usingCoinExchangeSet.getStopLossesRatio()));
        quantBotDetailDTO.setStopLossProfit(String.valueOf(usingCoinExchangeSet.getStopLossProfit()));
        quantBotDetailDTO.setAddPositionBackRatio(String.valueOf(usingCoinExchangeSet.getAddPositionBackRatio()));
        quantBotDetailDTO.setAddPositionTimesModelSwitch(usingCoinExchangeSet.getAddPositionTimesModelSwitch());
        quantBotDetailDTO.setAddPositionDynamicTimes(usingCoinExchangeSet.getAddPositionDynamicTimes());
        quantBotDetailDTO.setAddPositionFixTimes(usingCoinExchangeSet.getAddPositionFixTimes());
        quantBotDetailDTO.setAntiAddPositionTimesModelSwitch(usingCoinExchangeSet.getAntiAddPositionTimesModelSwitch());
        quantBotDetailDTO.setAntiAddPositionDynamicTimes(usingCoinExchangeSet.getAntiAddPositionDynamicTimes());
        quantBotDetailDTO.setAntiAddPositionFixTimes(usingCoinExchangeSet.getAntiAddPositionFixTimes());
        quantBotDetailDTO.setStrategyType(String.valueOf(usingCoinExchangeSet.getStrategyType()));
        quantBotDetailDTO.setStatus(UserBotStatusTypeEnum.ACTIVE.getCode());
        quantBotDetailDTO.setAddCount(String.valueOf(usingCoinExchangeSet.getMakeOrderNum()));
        quantBotDetailDTO.setDirection(dto.getDirection());
        quantBotDetailDTO.setLeverRate(String.valueOf(dto.getLeverRate()));
        quantBotDetailDTO.setBuyStopRate(String.valueOf(usingCoinExchangeSet.getBuyStopRate()));
        quantBotDetailDTO.setSellStopRate(String.valueOf(usingCoinExchangeSet.getSellStopRate()));
        quantBotDetailDTO.setGetOffAddPositionNum(String.valueOf(usingCoinExchangeSet.getGetOffAddPositionNum()));
        quantBotDetailDTO.setGetOffNeedTime(String.valueOf(usingCoinExchangeSet.getGetOffNeedTime()));
        quantBotDetailDTO.setGetOffProfitLine(String.valueOf(usingCoinExchangeSet.getGetOffProfitLine()));
        quantBotDetailDTO.setTotalStopLossNumLimitAddNum(String.valueOf(usingCoinExchangeSet.getTotalStopLossNumLimitAddNum()));
        quantBotDetailDTO.setAntiAddCount(String.valueOf(usingCoinExchangeSet.getAntiMakeOrderNum()));
        quantBotDetailDTO.setAntiAddPositionRatio1(String.valueOf(usingCoinExchangeSet.getAntiAddPosition1().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio2(String.valueOf(usingCoinExchangeSet.getAntiAddPosition2().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio3(String.valueOf(usingCoinExchangeSet.getAntiAddPosition3().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio4(String.valueOf(usingCoinExchangeSet.getAntiAddPosition4().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio5(String.valueOf(usingCoinExchangeSet.getAntiAddPosition5().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio6(String.valueOf(usingCoinExchangeSet.getAntiAddPosition6().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio7(String.valueOf(usingCoinExchangeSet.getAntiAddPosition7().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio8(String.valueOf(usingCoinExchangeSet.getAntiAddPosition8().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio9(String.valueOf(usingCoinExchangeSet.getAntiAddPosition9().abs()));
        quantBotDetailDTO.setAntiAddPositionRatio10(String.valueOf(usingCoinExchangeSet.getAntiAddPosition10().abs()));
        quantBotDetailDTO.setAntiStopProfitRatio(String.valueOf(usingCoinExchangeSet.getAntiStopProfitRatio()));
        return quantBotDetailDTO;
    }

    private CoinExchangeSet getUsingCoinExchangeSet(String userId, Integer exchangeType, String destinationCoin, String sourceCoin, String direction) {
        List<CoinExchangeSet> coinExchangeSets = coinExchangeSetMapperExt.queryCoinExchangeSetByUserIdExchangeTypeCoin(userId, exchangeType,
                destinationCoin, sourceCoin, direction);

        if (CollectionUtils.isEmpty(coinExchangeSets)) {
            return executeOrderServiceImpl.getQuanDefaultConfig(direction);
        } else {
            return coinExchangeSets.get(0);
        }
    }

    private BigDecimal getOffSetAmount(Integer exchangeType, String direction, Integer leverRate, String destinationCoin, String sourceCoin, String userId) {
        BigDecimal offSetAmount = BigDecimal.ZERO;
        String result = stringRedisTemplate.opsForValue().get(KeyContactUtil.getOffSetKey(exchangeType, direction, leverRate, destinationCoin, sourceCoin, userId));
        if (StringUtils.isEmpty(result)) {
            return offSetAmount;
        }
        List<OffSetDetailDTO> offSets = JSONArray.parseArray(result, OffSetDetailDTO.class);
        for (OffSetDetailDTO offSet : offSets) {
            offSetAmount = offSetAmount.add(new BigDecimal(offSet.getOffSetPositionPiece()));
        }

        return offSetAmount;
    }

    /**
     * 管理员更新币种交易设置
     *
     * @param updateStrategyByAdminReqDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UpdateStrategyByAdminRespDTO updateStrategyByAdmin(UpdateStrategyByAdminReqDTO updateStrategyByAdminReqDTO) {
        int successCount = 0;

        List<CoinExchangeSet> coinExchangeSets = coinExchangeSetMapperExt.selectByList(updateStrategyByAdminReqDTO);
        for (CoinExchangeSet coinExchangeSet : coinExchangeSets) {
            try {
                UpdateStrategyReqDTO updateStrategyReqDTO = toGetUpdateStrategyReqDTO(updateStrategyByAdminReqDTO, coinExchangeSet);
                toExecuteUpdateStrategy(updateStrategyReqDTO);
                successCount += 1;
            } catch (Exception e) {
                log.error("updateStrategyByAdmin更新失败", coinExchangeSet, e);
            }
        }

        UpdateStrategyByAdminRespDTO updateStrategyByAdminRespDTO = new UpdateStrategyByAdminRespDTO();
        updateStrategyByAdminRespDTO.setTotalCount(coinExchangeSets.size());
        updateStrategyByAdminRespDTO.setSuccessCount(successCount);
        return updateStrategyByAdminRespDTO;
    }

    private UpdateStrategyReqDTO toGetUpdateStrategyReqDTO(UpdateStrategyByAdminReqDTO updateStrategyByAdminReqDTO, CoinExchangeSet coinExchangeSet) {
        if (updateStrategyByAdminReqDTO.getInitOrderPosition() != null) {
            coinExchangeSet.setInitOrderPosition(updateStrategyByAdminReqDTO.getInitOrderPosition());
        }
        if (updateStrategyByAdminReqDTO.getMakeOrderNum() != null) {
            coinExchangeSet.setMakeOrderNum(updateStrategyByAdminReqDTO.getMakeOrderNum());
        }
        if (updateStrategyByAdminReqDTO.getStopProfitRatio() != null) {
            coinExchangeSet.setStopProfitRatio(updateStrategyByAdminReqDTO.getStopProfitRatio());
        }
        if (updateStrategyByAdminReqDTO.getStopProfitBackRatio() != null) {
            coinExchangeSet.setStopProfitBackRatio(updateStrategyByAdminReqDTO.getStopProfitBackRatio());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition1() != null) {
            coinExchangeSet.setAddPosition1(updateStrategyByAdminReqDTO.getAddPosition1());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition2() != null) {
            coinExchangeSet.setAddPosition2(updateStrategyByAdminReqDTO.getAddPosition2());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition3() != null) {
            coinExchangeSet.setAddPosition3(updateStrategyByAdminReqDTO.getAddPosition3());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition4() != null) {
            coinExchangeSet.setAddPosition4(updateStrategyByAdminReqDTO.getAddPosition4());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition5() != null) {
            coinExchangeSet.setAddPosition5(updateStrategyByAdminReqDTO.getAddPosition5());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition6() != null) {
            coinExchangeSet.setAddPosition6(updateStrategyByAdminReqDTO.getAddPosition6());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition7() != null) {
            coinExchangeSet.setAddPosition7(updateStrategyByAdminReqDTO.getAddPosition7());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition8() != null) {
            coinExchangeSet.setAddPosition8(updateStrategyByAdminReqDTO.getAddPosition8());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition9() != null) {
            coinExchangeSet.setAddPosition9(updateStrategyByAdminReqDTO.getAddPosition9());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition10() != null) {
            coinExchangeSet.setAddPosition10(updateStrategyByAdminReqDTO.getAddPosition10());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition11() != null) {
            coinExchangeSet.setAddPosition11(updateStrategyByAdminReqDTO.getAddPosition11());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition12() != null) {
            coinExchangeSet.setAddPosition12(updateStrategyByAdminReqDTO.getAddPosition12());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition13() != null) {
            coinExchangeSet.setAddPosition13(updateStrategyByAdminReqDTO.getAddPosition13());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition14() != null) {
            coinExchangeSet.setAddPosition14(updateStrategyByAdminReqDTO.getAddPosition14());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition15() != null) {
            coinExchangeSet.setAddPosition15(updateStrategyByAdminReqDTO.getAddPosition15());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition16() != null) {
            coinExchangeSet.setAddPosition16(updateStrategyByAdminReqDTO.getAddPosition16());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition17() != null) {
            coinExchangeSet.setAddPosition17(updateStrategyByAdminReqDTO.getAddPosition17());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition18() != null) {
            coinExchangeSet.setAddPosition18(updateStrategyByAdminReqDTO.getAddPosition18());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition19() != null) {
            coinExchangeSet.setAddPosition19(updateStrategyByAdminReqDTO.getAddPosition19());
        }
        if (updateStrategyByAdminReqDTO.getAddPosition20() != null) {
            coinExchangeSet.setAddPosition20(updateStrategyByAdminReqDTO.getAddPosition20());
        }
        if (updateStrategyByAdminReqDTO.getStopLossesRatio() != null) {
            coinExchangeSet.setStopLossesRatio(updateStrategyByAdminReqDTO.getStopLossesRatio());
        }
        if (updateStrategyByAdminReqDTO.getStopLossProfit() != null) {
            coinExchangeSet.setStopLossProfit(updateStrategyByAdminReqDTO.getStopLossProfit());
        }
        if (updateStrategyByAdminReqDTO.getAddPositionBackRatio() != null) {
            coinExchangeSet.setAddPositionBackRatio(updateStrategyByAdminReqDTO.getAddPositionBackRatio());
        }
        if (updateStrategyByAdminReqDTO.getStrategyType() != null) {
            coinExchangeSet.setStrategyType(updateStrategyByAdminReqDTO.getStrategyType());
        }
        if (updateStrategyByAdminReqDTO.getAddPositionTimesModelSwitch() != null) {
            coinExchangeSet.setAddPositionTimesModelSwitch(updateStrategyByAdminReqDTO.getAddPositionTimesModelSwitch());
        }
        if (updateStrategyByAdminReqDTO.getAddPositionDynamicTimes() != null) {
            coinExchangeSet.setAddPositionDynamicTimes(updateStrategyByAdminReqDTO.getAddPositionDynamicTimes());
        }
        if (updateStrategyByAdminReqDTO.getAddPositionFixTimes() != null) {
            coinExchangeSet.setAddPositionFixTimes(updateStrategyByAdminReqDTO.getAddPositionFixTimes());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPositionTimesModelSwitch() != null) {
            coinExchangeSet.setAntiAddPositionTimesModelSwitch(updateStrategyByAdminReqDTO.getAntiAddPositionTimesModelSwitch());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPositionDynamicTimes() != null) {
            coinExchangeSet.setAntiAddPositionDynamicTimes(updateStrategyByAdminReqDTO.getAntiAddPositionDynamicTimes());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPositionFixTimes() != null) {
            coinExchangeSet.setAntiAddPositionFixTimes(updateStrategyByAdminReqDTO.getAntiAddPositionFixTimes());
        }
        if (updateStrategyByAdminReqDTO.getBuyStopRate() != null) {
            coinExchangeSet.setBuyStopRate(updateStrategyByAdminReqDTO.getBuyStopRate());
        }
        if (updateStrategyByAdminReqDTO.getSellStopRate() != null) {
            coinExchangeSet.setSellStopRate(updateStrategyByAdminReqDTO.getSellStopRate());
        }
        if (updateStrategyByAdminReqDTO.getGetOffAddPositionNum() != null) {
            coinExchangeSet.setGetOffAddPositionNum(updateStrategyByAdminReqDTO.getGetOffAddPositionNum());
        }
        if (updateStrategyByAdminReqDTO.getGetOffNeedTime() != null) {
            coinExchangeSet.setGetOffNeedTime(updateStrategyByAdminReqDTO.getGetOffNeedTime());
        }
        if (updateStrategyByAdminReqDTO.getGetOffProfitLine() != null) {
            coinExchangeSet.setGetOffProfitLine(updateStrategyByAdminReqDTO.getGetOffProfitLine());
        }
        if (updateStrategyByAdminReqDTO.getTotalStopLossNumLimitAddNum() != null) {
            coinExchangeSet.setTotalStopLossNumLimitAddNum(updateStrategyByAdminReqDTO.getTotalStopLossNumLimitAddNum());
        }
        if (updateStrategyByAdminReqDTO.getAntiMakeOrderNum() != null) {
            coinExchangeSet.setAntiMakeOrderNum(updateStrategyByAdminReqDTO.getAntiMakeOrderNum());
        }
        if (updateStrategyByAdminReqDTO.getAntiStopProfitRatio() != null) {
            coinExchangeSet.setAntiStopProfitRatio(updateStrategyByAdminReqDTO.getAntiStopProfitRatio());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition1() != null) {
            coinExchangeSet.setAntiAddPosition1(updateStrategyByAdminReqDTO.getAntiAddPosition1());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition2() != null) {
            coinExchangeSet.setAntiAddPosition2(updateStrategyByAdminReqDTO.getAntiAddPosition2());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition3() != null) {
            coinExchangeSet.setAntiAddPosition3(updateStrategyByAdminReqDTO.getAntiAddPosition3());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition4() != null) {
            coinExchangeSet.setAntiAddPosition4(updateStrategyByAdminReqDTO.getAntiAddPosition4());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition5() != null) {
            coinExchangeSet.setAntiAddPosition5(updateStrategyByAdminReqDTO.getAntiAddPosition5());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition6() != null) {
            coinExchangeSet.setAntiAddPosition6(updateStrategyByAdminReqDTO.getAntiAddPosition6());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition7() != null) {
            coinExchangeSet.setAntiAddPosition7(updateStrategyByAdminReqDTO.getAntiAddPosition7());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition8() != null) {
            coinExchangeSet.setAntiAddPosition8(updateStrategyByAdminReqDTO.getAntiAddPosition8());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition9() != null) {
            coinExchangeSet.setAntiAddPosition9(updateStrategyByAdminReqDTO.getAntiAddPosition9());
        }
        if (updateStrategyByAdminReqDTO.getAntiAddPosition10() != null) {
            coinExchangeSet.setAntiAddPosition10(updateStrategyByAdminReqDTO.getAntiAddPosition10());
        }
        UpdateStrategyReqDTO convert = ConvertUtils.convert(coinExchangeSet, UpdateStrategyReqDTO.class);
        return convert;
    }

}
